#include "config.h"
#include "fonts_manager.h"
#include "recv.h"

#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>


int      g_iReaderFontSize = 24;             /*电子书阅读字体大小*/
char     g_cFontsFile[16]  = "STSONG.TTF";   /*字体风格文件路径*/
uint32_t g_BackGroundColor = 0xE7DBB5;       /*背景颜色*/
uint32_t g_FontsColor      = 0x514438;       /*字体颜色*/

/**
 * @brief 配置字体信息
 * 
 * @param pcRevBuf  收到的其他进程信息
 * @param pcSendBuf 回复其他进程的信息
 */
static void Cmd_SetFontDetail(char *pcRevBuf,char *pcSendBuf)
{
    int iRet = 0;
    char* temp;
    char cFontsFile[16];
    uint32_t dwFontSize;
    //uint32_t tmep;

    pcSendBuf[1] = 4;

    memcpy(&dwFontSize,pcRevBuf+2,4);
    //dwFontSize = ntohl(tmep);
    memcpy(cFontsFile,pcRevBuf+6,16);
    //DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"%s %d dwFontSize:%d cFontsFile:%s\r\n",__func__,__LINE__,dwFontSize,cFontsFile);
    if(dwFontSize==g_iReaderFontSize&&!strcmp(cFontsFile,g_cFontsFile))
    {
        pcSendBuf[3] = 1;
        return;
    }

    /*不改变字体文件*/
    if(strcmp(cFontsFile,"default")){
        temp = strdup(cFontsFile);
    }else{
        temp = strdup(g_cFontsFile);
    }
    /*不改变字体大小*/
    if(dwFontSize == 0){
        dwFontSize = g_iReaderFontSize;
    }

    iRet = SetFontsDetail(FONT_LIB_NAME,temp,dwFontSize);
    if(iRet){
        pcSendBuf[3] = -1;
        DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"set fonts detail failed!cFontsFile:%s dwFontSize:%d\r\n",temp,dwFontSize);
    }else{
        g_iReaderFontSize = dwFontSize;
        memcpy(g_cFontsFile,temp,16);
        pcSendBuf[3] = 0;
    }  
}

/**
 * @brief 获取字体信息
 * 
 * @param pcSendBuf 回复其他进程的信息
 */
static void Cmd_GetFontDetail(char *pcSendBuf)
{
    pcSendBuf[1] = 22;
    memcpy(pcSendBuf+2,&g_iReaderFontSize,4);
    memcpy(pcSendBuf+6,g_cFontsFile,sizeof(g_cFontsFile));
}

/**
 * @brief 设置颜色
 * 
 * @param pcRevBuf  收到的其他进程信息
 * @param pcSendBuf 回复其他进程的信息
 */
static void Cmd_SetColor(char *pcRevBuf,char *pcSendBuf)
{
    pcSendBuf[1] = 4;
    if(pcRevBuf[2]){
        memcpy(&g_FontsColor,pcRevBuf+3,4);
    }else{
        memcpy(&g_BackGroundColor,pcRevBuf+3,4);
    }
    pcSendBuf[3] = 0;
}

/**
 * @brief 获取颜色数据
 * 
 * @param pcRevBuf  收到的其他进程信息
 * @param pcSendBuf 回复其他进程的信息
 */
static void Cmd_GetColor(char *pcRevBuf,char *pcSendBuf)
{
    pcSendBuf[1] = 6;
    if(pcRevBuf[2]){
        memcpy(pcSendBuf+2,&g_FontsColor,4);
    }else{
        memcpy(pcSendBuf+2,&g_BackGroundColor,4);
    }
}

/**
 * @brief 设置Dlog过滤等级
 */
static void Cmd_SetDlogLvl(char *pcRevBuf,char *pcSendBuf)
{
    pcSendBuf[1] = 4;

    dlog_set_level(pcRevBuf[2]);

    pcSendBuf[3] = 0;
}

/**
 * @brief 获取Dlog过滤等级
 */
static void Cmd_GetDlogLvl(char *pcSendBuf)
{

    pcSendBuf[1] = 4;

    pcSendBuf[2] = dlog_get_level();

    pcSendBuf[3] = 0;
}

/**
 * @brief 设置Dlog输出格式
 */
static void Cmd_SetDlogFmt(char *pcRevBuf,char *pcSendBuf)
{
    uint16_t tmp;

    pcSendBuf[1] = 4;

    memcpy(&tmp,pcRevBuf+3,2);
    dlog_set_fmt(pcRevBuf[2],tmp);

    pcSendBuf[3] = 0;
}

/**
 * @brief 获取Dlog输出格式
 */
static void Cmd_GetDlogFmt(char *pcRevBuf,char *pcSendBuf)
{
    uint16_t tmp = 0;

    pcSendBuf[1] = 4;

    tmp = dlog_get_fmt(pcRevBuf[2]);

    memcpy(pcSendBuf+2,&tmp,2);

    pcSendBuf[3] = 0;

}

/**
 * @brief 分析处理收到的数据
 * 
 * @param pcRevBuf  收到的其他进程信息
 * @param pcSendBuf 回复其他进程的信息
 */
static void ParseCmd(char *pcRevBuf,char * pcSendBuf)
{
	char cmd_id = pcRevBuf[0];

    pcSendBuf[0] = pcRevBuf[0];
    
    //DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"cmd_id:%x\r\n",cmd_id);
	switch (cmd_id)
	{
	case CMD_SET_FONT_DETAIL:
        Cmd_SetFontDetail(pcRevBuf,pcSendBuf);
		break;
	case CMD_GET_FONT_DETAIL:
        Cmd_GetFontDetail(pcSendBuf);
		break;
	case CMD_SET_COLOR:
        Cmd_SetColor(pcRevBuf,pcSendBuf);
		break;
	case CMD_GET_COLOR:
        Cmd_GetColor(pcRevBuf,pcSendBuf);
		break;
	case CMD_SET_DLOG_LVL:
        Cmd_SetDlogLvl(pcRevBuf,pcSendBuf);
		break;
	case CMD_GET_DLOG_LVL:
        Cmd_GetDlogLvl(pcSendBuf);
		break;
	case CMD_SET_DLOG_FMT:
        Cmd_SetDlogFmt(pcRevBuf,pcSendBuf);
		break;
	case CMD_GET_DLOG_FMT:
        Cmd_GetDlogFmt(pcRevBuf,pcSendBuf);
		break;
	default:
        pcSendBuf[1] = 4;
        pcSendBuf[3] = -1;
        DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"cmd_id[%x] is not supported!",cmd_id);
		break;
	}
}

/**
 * @brief 接受其他进程的数据并分析处理 线程函数
 */
void *ParseMsg()
{
	int server_fd;
    int sock_fd;
    struct sockaddr_un server_addr, client_addr;
    char cRevBuf[BUF_SIZE] = {0};
    char cSendBuf[64];

    // 创建套接字
    if ((server_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"can't creat socket");
        exit(EXIT_FAILURE);
    }
	// 设置服务器地址
    memset(&server_addr, 0, sizeof(struct sockaddr_un));
    server_addr.sun_family = AF_UNIX;
    strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1);

    // 绑定套接字到路径
    unlink(SOCKET_PATH);
    if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_un)) == -1) {
        DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"bind sock error");
        close(server_fd);
        exit(EXIT_FAILURE);
    }
	// 监听连接
	if (listen(server_fd, 5) == -1) {
		DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"listen port error");
		close(server_fd);
		exit(EXIT_FAILURE);
	}
	while(1){

		// 接受客户端连接
		socklen_t client_len = sizeof(struct sockaddr_un);

		if ((sock_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len)) == -1) {
			DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"accept client error");
			close(server_fd);
			exit(EXIT_FAILURE);
		}
		// 读取客户端发送的数据
		memset(cRevBuf,0x00,sizeof(cRevBuf));
		read(sock_fd, cRevBuf, BUF_SIZE);

		if(cRevBuf[0]>0x80){
			ParseCmd(cRevBuf,cSendBuf);
		}

        if (send(sock_fd, cSendBuf,cSendBuf[1], 0) == -1) {
            DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"Send message failed");
            close(sock_fd);
        }
	}
    // 关闭套接字
    close(sock_fd);
    close(server_fd);
    unlink(SOCKET_PATH);  
    return 0;
}

